//==============================================================================
// FileUtils.cc
//----------------------------------------------------------------------------
// Miscellaneous file utilities... things that are commonly enough 
// done to make available as stand alone functions. 
//
//------------------------------------------------------------------------------
// $Id: FileUtils.cc,v 1.1 2000/01/31 21:13:50 kdurbin Exp kdurbin $
//------------------------------------------------------------------------------
// $Log: FileUtils.cc,v $
// Revision 1.1  2000/01/31 21:13:50  kdurbin
// Initial revision
//
//   
//==============================================================================
//.......1.........2.........3.........4.........5.........6.........7.........8
//

#include "FileUtils.hh"

int FileSize(string FileName)
{
  struct stat results;
  if (stat(FileName.c_str(),&results) == 0){
	 return(results.st_size);
  }else{
	 return(-1);
  }
}


//---------------------------------------------------
// * FileIsNewerThan
//---------------------------------------------------
//
// 
bool FileIsNewerThan(string FileName,int tyear, int tmonth,int tday)
{
  struct stat results;
  if (stat(FileName.c_str(),&results) == 0){
	 time_t rawtime = results.st_ctime; 
	 
	 struct tm *timeinfo;
	 timeinfo = localtime(&rawtime);
			 
	 int fYear = timeinfo->tm_year+1900;
	 int fmonth = timeinfo->tm_mon + 1;
	 int fday = timeinfo->tm_mday;
	 
	 if (fYear > tyear) return(true);
	 if (fYear == tyear){
		if (fmonth > tmonth) return(true);
		if (fmonth == tmonth){
		  if (fday > tday) return(true);
		  else return(false);
		}
	 }
  }
  return(false);
}



//---------------------------------------------------
// * GetDateStamp
//---------------------------------------------------
//
string GetDateStamp(string FileName)
{
  struct stat results;
  if (stat(FileName.c_str(),&results) == 0){
	 time_t rawtime = results.st_ctime; 

	 struct tm *timeinfo;
	 timeinfo = localtime(&rawtime);

	 int fullYear = timeinfo->tm_year+1900;
	 int month = timeinfo->tm_mon + 1;
	 int day = timeinfo->tm_mday;

	 char buf[500];
	 sprintf(buf,"%04d%02d%02d",fullYear,month,day);
	 string rValue = buf;
	 return(rValue);	 	 
  }else{
	 // Something went wrong.  
	 return("00000000");
  }
}

/*

//---------------------------------------------------
// * CreateTemporaryFileName
//---------------------------------------------------
// DEPRECATED.  USE UniquifyName instead. 
// 
//
string CreateTemporaryFileName(char *rootName)
{
  string temp;
  temp = rootName;
  return(CreateTemporaryFileName(temp));
}


//---------------------------------------------------
// * CreateTemporaryFileName
//---------------------------------------------------
// DEPRECATED.  USE UniquifyName instead. 
//
string CreateTemporaryFileName(string rootName)
{
  RandomNumberGenerator RNG;
  RNG.SeedWithClock();
  long rndSuffix = (long) RNG.Uniform(0,RAND_MAX);
  char buf[80];
  sprintf(buf,"%ld",rndSuffix);
  string temp = rootName+buf;
  return(temp);
}
*/

//----------------------------------------
// * FileExists
//----------------------------------------
bool FileExists(string FileName)
{
  ifstream testin;
  testin.open(FileName.c_str());
  if (testin.fail()) return(false);
  else{ 
	 testin.close();
	 return(true);
  }
}

//----------------------------------------
// * UniquifyName
//----------------------------------------
string UniquifyName(string NameStart,string NameEnd)
{
  int idx = 0;
  do{
	 string testName = NameStart+itoa(idx)+NameEnd;
	 if (!FileExists(testName)){
		return(testName);
	 }
	 idx++;
  }while(1); 
}


//----------------------------------------
// * UniquifyName
//----------------------------------------
//
void OpenOrDie(string FileName,ifstream &fin){
  fin.open(FileName.c_str());
  if (fin.fail()){
	 cerr<<"Unable to open "<<FileName<<endl;
	 exit(1);
  }
}

//----------------------------------------
// * UniquifyName
//----------------------------------------
//
void OpenOrDie(string FileName,ofstream &fin){
  fin.open(FileName.c_str());
  if (fin.fail()){
	 cerr<<"Unable to open "<<FileName<<endl;
	 exit(1);
  }
}

//---------------------------------------------------
// * GetFileSuffix
//---------------------------------------------------
// Returns the last suffix of a string (i.e. characters 
// after the last ".").
//
string GetFileSuffix(string source)
{ 
  int LastDotIdx = source.rfind(".");
  if (LastDotIdx < 0){
    return("");
  }

  int SuffixSize = source.size() - LastDotIdx - 1;
  return(source.substr(LastDotIdx+1,SuffixSize));
}

//---------------------------------------------------
// * ReadFOF
//---------------------------------------------------
// Reads a list of names from a file.  Assumes the 
// file contains nothing but names, one to a line. 
//
void ReadFOF(string &FileName,vector<string> &Names){
  ifstream NFile;

  // Read in a list of file names from a file of files
  NFile.open(FileName.c_str());
  if (NFile.fail()){
	 cout<<"ERROR: Could not open "<<FileName<<endl;
	 return;
  }
  do{
	 string temp;
	 GetLine(NFile,temp);

	 StripWhiteSpace(temp); // KJD Should be StripTrailingWhiteSpace

	 // Want to skip blank lines
	 if (temp.size() > 0){
		Names.push_back(temp);
	 }
  }while(!NFile.eof());
  NFile.close();
}

//---------------------------------------------------
// * ReadFOF
//---------------------------------------------------
//
void ReadFOF(const char *pFileName,vector<string> &Names)
{
  string Temp = pFileName;
  ReadFOF(Temp,Names);
}


//---------------------------------------------------
// * WriteFOF
//---------------------------------------------------
//
//
void WriteFOF(string &FileName,vector<string> &Names){
  ofstream OutFile;

  // Read in a list of file names from a file of files
  OutFile.open(FileName.c_str());
  for(int i = 0;i<Names.size();i++){
	 OutFile<<Names[i]<<endl;
  }
  OutFile.close();
}


//---------------------------------------------------
// * open
//---------------------------------------------------
// Does an open that is agnostic about whether a file
// has a .gz extension or not, or whether it is actually
// gzipped or not.  
// 
// Note: the izipstream version of fail() does not work. 
// That's why this function uses FileExists, which in 
// turn uses a regular ifstream for the test. 
//
bool
icbtstream::open(string FileName){

  // Try the file name as given....
  if (FileExists(FileName)){
	 izipstream::open(FileName.c_str());
  }else{
	 // Try it without the .gz if it has .gz ...
	 if (Contains(FileName,".gz")){
		int idx = FileName.rfind(".gz");
		string FileRoot = FileName.substr(0,idx);
		cout<<"FileRoot="<<FileRoot<<endl;
		if (FileExists(FileRoot)){
		  izipstream::open(FileRoot.c_str());
		}else return(false); // Neither plain nor .gz file exists. 
	 }else{
		// Try it with .gz if it didn't have it...
		FileName+=".gz";
		if (FileExists(FileName)){
		  izipstream::open(FileName.c_str());
		}else return(false);
	 }
  }
  return(true);
}

